/*!
 * # Fomantic-UI - Transition
 * https://github.com/fomantic/Fomantic-UI/
 *
 *
 * Released under the MIT license
 * https://opensource.org/licenses/MIT
 *
 */

(function ($, window, document) {
    'use strict';

    function isFunction(obj) {
        return typeof obj === 'function' && typeof obj.nodeType !== 'number';
    }

    window = window !== undefined && window.Math === Math
        ? window
        : globalThis;

    $.fn.transition = function () {
        var
            $allModules     = $(this),

            time            = Date.now(),
            performance     = [],

            moduleArguments = arguments,
            query           = moduleArguments[0],
            queryArguments  = [].slice.call(arguments, 1),
            methodInvoked   = typeof query === 'string',

            returnedValue
        ;
        $allModules.each(function (index) {
            var
                $module  = $(this),
                element  = this,

                // set at run time
                settings,
                instance,

                error,
                className,
                metadata,

                moduleNamespace,
                eventNamespace,
                module
            ;

            module = {

                initialize: function () {
                    // get full settings
                    settings = module.get.settings.apply(element, moduleArguments);

                    // shorthand
                    className = settings.className;
                    error = settings.error;
                    metadata = settings.metadata;

                    // define namespace
                    eventNamespace = '.' + settings.namespace;
                    moduleNamespace = 'module-' + settings.namespace;
                    instance = $module.data(moduleNamespace) || module;

                    if (methodInvoked) {
                        methodInvoked = module.invoke(query);
                    }

                    // method not invoked, lets run an animation
                    if (methodInvoked === false) {
                        module.verbose('Converted arguments into settings object', settings);
                        if (settings.interval) {
                            module.delay(settings.interval);
                        } else {
                            module.animate();
                        }
                        module.instantiate();
                    }
                },

                instantiate: function () {
                    module.verbose('Storing instance of module', module);
                    instance = module;
                    $module
                        .data(moduleNamespace, instance)
                    ;
                },

                destroy: function () {
                    module.verbose('Destroying previous module for', element);
                    $module
                        .removeData(moduleNamespace)
                    ;
                },

                refresh: function () {
                    module.verbose('Refreshing display type on next animation');
                    delete module.displayType;
                },

                forceRepaint: function () {
                    module.verbose('Forcing element repaint');
                    var
                        $parentElement = $module.parent(),
                        $nextElement = $module.next()
                    ;
                    if ($nextElement.length === 0) {
                        $module.detach().appendTo($parentElement);
                    } else {
                        $module.detach().insertBefore($nextElement);
                    }
                },

                repaint: function () {
                    module.verbose('Repainting element');
                    var
                        fakeAssignment = element.offsetWidth
                    ;
                },

                delay: function (interval) {
                    var
                        direction = module.get.animationDirection(),
                        shouldReverse,
                        delay
                    ;
                    if (!direction) {
                        direction = module.can.transition()
                            ? module.get.direction()
                            : 'static';
                    }
                    interval = interval !== undefined
                        ? interval
                        : settings.interval;
                    shouldReverse = settings.reverse === 'auto' && direction === className.outward;
                    delay = shouldReverse || settings.reverse === true
                        ? ($allModules.length - index) * interval
                        : index * interval;
                    module.debug('Delaying animation by', delay);
                    setTimeout(function () { module.animate(); }, delay);
                },

                animate: function (overrideSettings) {
                    settings = overrideSettings || settings;

                    module.debug('Preparing animation', settings.animation);
                    if (module.is.animating()) {
                        if (settings.queue) {
                            if (!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
                                module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
                            } else {
                                module.queue(settings.animation);
                            }

                            return false;
                        }
                        if (!settings.allowRepeats && module.is.occurring()) {
                            module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);

                            return false;
                        }

                        module.debug('New animation started, completing previous early', settings.animation);
                        instance.complete();
                    }
                    if (module.can.animate()) {
                        module.set.animating(settings.animation);
                    } else {
                        module.error(error.noAnimation, settings.animation, element);
                    }
                },

                reset: function () {
                    module.debug('Resetting animation to beginning conditions');
                    module.remove.animationCallbacks();
                    module.restore.conditions();
                    module.remove.animating();
                },

                queue: function (animation) {
                    module.debug('Queueing animation of', animation);
                    module.queuing = true;
                    $module
                        .one('animationend.queue' + eventNamespace, function () {
                            module.queuing = false;
                            module.repaint();
                            module.animate.apply(this, settings);
                        })
                    ;
                },

                complete: function (event) {
                    if (event && event.target === element) {
                        event.stopPropagation();
                    }
                    module.debug('Animation complete', settings.animation);
                    module.remove.completeCallback();
                    module.remove.failSafe();
                    if (!module.is.looping()) {
                        if (module.is.outward()) {
                            module.verbose('Animation is outward, hiding element');
                            module.restore.conditions();
                            module.hide();
                        } else if (module.is.inward()) {
                            module.verbose('Animation is inward, showing element');
                            module.restore.conditions();
                            module.show();
                        } else {
                            module.verbose('Static animation completed');
                            module.restore.conditions();
                            settings.onComplete.call(element);
                        }
                    }
                },

                force: {
                    visible: function () {
                        var
                            style          = $module.attr('style'),
                            userStyle      = module.get.userStyle(style),
                            displayType    = module.get.displayType(),
                            overrideStyle  = userStyle + 'display: ' + displayType + ' !important;',
                            inlineDisplay  = $module[0].style.display,
                            mustStayHidden = !displayType || (inlineDisplay === 'none' && settings.skipInlineHidden) || $module[0].tagName.match(/(script|link|style)/i)
                        ;
                        if (mustStayHidden) {
                            module.remove.transition();

                            return false;
                        }
                        module.verbose('Overriding default display to show element', displayType);
                        $module
                            .attr('style', overrideStyle)
                        ;

                        return true;
                    },
                    hidden: function () {
                        var
                            style          = $module.attr('style'),
                            currentDisplay = $module.css('display'),
                            emptyStyle     = style === undefined || style === ''
                        ;
                        if (currentDisplay !== 'none' && !module.is.hidden()) {
                            module.verbose('Overriding default display to hide element');
                            $module
                                .css('display', 'none')
                            ;
                        } else if (emptyStyle) {
                            $module
                                .removeAttr('style')
                            ;
                        }
                    },
                },

                has: {
                    direction: function (animation) {
                        var
                            hasDirection = false
                        ;
                        animation = animation || settings.animation;
                        if (typeof animation === 'string') {
                            animation = animation.split(' ');
                            $.each(animation, function (index, word) {
                                if (word === className.inward || word === className.outward) {
                                    hasDirection = true;
                                }
                            });
                        }

                        return hasDirection;
                    },
                    inlineDisplay: function () {
                        var
                            style = $module.attr('style') || ''
                        ;

                        return Array.isArray(style.match(/display.*?;/, ''));
                    },
                },

                set: {
                    animating: function (animation) {
                        // remove previous callbacks
                        module.remove.completeCallback();

                        // determine exact animation
                        animation = animation || settings.animation;
                        var animationClass = module.get.animationClass(animation);

                        // save animation class in cache to restore class names
                        module.save.animation(animationClass);

                        if (module.force.visible()) {
                            module.remove.hidden();
                            module.remove.direction();

                            module.start.animation(animationClass);
                        }
                    },
                    duration: function (animationName, duration) {
                        duration = duration || settings.duration;
                        duration = typeof duration === 'number'
                            ? duration + 'ms'
                            : duration;
                        if (duration || duration === 0) {
                            module.verbose('Setting animation duration', duration);
                            $module
                                .css({
                                    'animation-duration': duration,
                                })
                            ;
                        }
                    },
                    direction: function (direction) {
                        direction = direction || module.get.direction();
                        if (direction === className.inward) {
                            module.set.inward();
                        } else {
                            module.set.outward();
                        }
                    },
                    looping: function () {
                        module.debug('Transition set to loop');
                        $module
                            .addClass(className.looping)
                        ;
                    },
                    hidden: function () {
                        $module
                            .addClass(className.transition)
                            .addClass(className.hidden)
                        ;
                    },
                    inward: function () {
                        module.debug('Setting direction to inward');
                        $module
                            .removeClass(className.outward)
                            .addClass(className.inward)
                        ;
                    },
                    outward: function () {
                        module.debug('Setting direction to outward');
                        $module
                            .removeClass(className.inward)
                            .addClass(className.outward)
                        ;
                    },
                    visible: function () {
                        $module
                            .addClass(className.transition)
                            .addClass(className.visible)
                        ;
                    },
                },

                start: {
                    animation: function (animationClass) {
                        animationClass = animationClass || module.get.animationClass();
                        module.debug('Starting tween', animationClass);
                        $module
                            .addClass(animationClass)
                            .one('animationend.complete' + eventNamespace, module.complete)
                        ;
                        if (settings.useFailSafe) {
                            module.add.failSafe();
                        }
                        module.set.duration(settings.duration);
                        settings.onStart.call(element);
                    },
                },

                save: {
                    animation: function (animation) {
                        if (!module.cache) {
                            module.cache = {};
                        }
                        module.cache.animation = animation;
                    },
                    displayType: function (displayType) {
                        if (displayType !== 'none') {
                            $module.data(metadata.displayType, displayType);
                        }
                    },
                    transitionExists: function (animation, exists) {
                        $.fn.transition.exists[animation] = exists;
                        module.verbose('Saving existence of transition', animation, exists);
                    },
                },

                restore: {
                    conditions: function () {
                        var
                            animation = module.get.currentAnimation()
                        ;
                        if (animation) {
                            $module
                                .removeClass(animation)
                            ;
                            module.verbose('Removing animation class', module.cache);
                        }
                        module.remove.duration();
                    },
                },

                add: {
                    failSafe: function () {
                        var
                            duration = module.get.duration()
                        ;
                        module.timer = setTimeout(function () {
                            $module.triggerHandler('animationend');
                        }, duration + settings.failSafeDelay);
                        module.verbose('Adding fail safe timer', module.timer);
                    },
                },

                remove: {
                    animating: function () {
                        $module.removeClass(className.animating);
                    },
                    animationCallbacks: function () {
                        module.remove.queueCallback();
                        module.remove.completeCallback();
                    },
                    queueCallback: function () {
                        $module.off('.queue' + eventNamespace);
                    },
                    completeCallback: function () {
                        $module.off('.complete' + eventNamespace);
                    },
                    display: function () {
                        $module.css('display', '');
                    },
                    direction: function () {
                        $module
                            .removeClass(className.inward)
                            .removeClass(className.outward)
                        ;
                    },
                    duration: function () {
                        $module
                            .css('animation-duration', '')
                        ;
                    },
                    failSafe: function () {
                        module.verbose('Removing fail safe timer', module.timer);
                        if (module.timer) {
                            clearTimeout(module.timer);
                        }
                    },
                    hidden: function () {
                        $module.removeClass(className.hidden);
                    },
                    visible: function () {
                        $module.removeClass(className.visible);
                    },
                    looping: function () {
                        module.debug('Transitions are no longer looping');
                        if (module.is.looping()) {
                            module.reset();
                            $module
                                .removeClass(className.looping)
                            ;
                        }
                    },
                    transition: function () {
                        $module
                            .removeClass(className.transition)
                            .removeClass(className.visible)
                            .removeClass(className.hidden)
                        ;
                    },
                },
                get: {
                    settings: function (animation, duration, onComplete) {
                        if (typeof animation === 'object') { // single settings object
                            return $.extend(true, {}, $.fn.transition.settings, animation);
                        }
                        if (typeof onComplete === 'function') { // all arguments provided
                            return $.extend({}, $.fn.transition.settings, {
                                animation: animation,
                                onComplete: onComplete,
                                duration: duration,
                            });
                        }
                        if (typeof duration === 'string' || typeof duration === 'number') { // only duration provided
                            return $.extend({}, $.fn.transition.settings, {
                                animation: animation,
                                duration: duration,
                            });
                        }
                        if (typeof duration === 'object') { // duration is actually settings object
                            return $.extend({}, $.fn.transition.settings, duration, {
                                animation: animation,
                            });
                        }
                        if (typeof duration === 'function') { // duration is actually callback
                            return $.extend({}, $.fn.transition.settings, {
                                animation: animation,
                                onComplete: duration,
                            });
                        }

                        // only animation provided
                        return $.extend({}, $.fn.transition.settings, {
                            animation: animation,
                        });
                    },
                    animationClass: function (animation) {
                        var
                            animationClass = animation || settings.animation,
                            directionClass = module.can.transition() && !module.has.direction()
                                ? module.get.direction() + ' '
                                : ''
                        ;

                        return className.animating + ' '
                            + className.transition + ' '
                            + directionClass
                            + animationClass;
                    },
                    currentAnimation: function () {
                        return module.cache && module.cache.animation !== undefined
                            ? module.cache.animation
                            : false;
                    },
                    currentDirection: function () {
                        return module.is.inward()
                            ? className.inward
                            : className.outward;
                    },
                    direction: function () {
                        return module.is.hidden() || !module.is.visible()
                            ? className.inward
                            : className.outward;
                    },
                    animationDirection: function (animation) {
                        var
                            direction
                        ;
                        animation = animation || settings.animation;
                        if (typeof animation === 'string') {
                            animation = animation.split(' ');
                            // search animation name for out/in class
                            $.each(animation, function (index, word) {
                                if (word === className.inward) {
                                    direction = className.inward;
                                } else if (word === className.outward) {
                                    direction = className.outward;
                                }
                            });
                        }
                        // return found direction
                        if (direction) {
                            return direction;
                        }

                        return false;
                    },
                    duration: function (duration) {
                        duration = duration || settings.duration;
                        if (duration === false) {
                            duration = $module.css('animation-duration') || 0;
                        }

                        return typeof duration === 'string'
                            ? (duration.indexOf('ms') > -1
                                ? parseFloat(duration)
                                : parseFloat(duration) * 1000)
                            : duration;
                    },
                    displayType: function (shouldDetermine) {
                        shouldDetermine = shouldDetermine !== undefined
                            ? shouldDetermine
                            : true;
                        if (settings.displayType) {
                            return settings.displayType;
                        }
                        if (shouldDetermine && $module.data(metadata.displayType) === undefined) {
                            var currentDisplay = $module.css('display');
                            if (currentDisplay === '' || currentDisplay === 'none') {
                                // create fake element to determine display state
                                module.can.transition(true);
                            } else {
                                module.save.displayType(currentDisplay);
                            }
                        }

                        return $module.data(metadata.displayType);
                    },
                    userStyle: function (style) {
                        style = style || $module.attr('style') || '';

                        return style.replace(/display.*?;/, '');
                    },
                    transitionExists: function (animation) {
                        return $.fn.transition.exists[animation];
                    },
                },

                can: {
                    transition: function (forced) {
                        var
                            animation         = settings.animation,
                            transitionExists  = module.get.transitionExists(animation),
                            displayType       = module.get.displayType(false),
                            elementClass,
                            tagName,
                            $clone,
                            currentAnimation,
                            inAnimation,
                            directionExists
                        ;
                        if (transitionExists === undefined || forced) {
                            module.verbose('Determining whether animation exists');
                            elementClass = $module.attr('class');
                            tagName = $module.prop('tagName');

                            $clone = $('<' + tagName + ' />').addClass(elementClass).insertAfter($module);
                            currentAnimation = $clone
                                .addClass(animation)
                                .removeClass(className.inward)
                                .removeClass(className.outward)
                                .addClass(className.animating)
                                .addClass(className.transition)
                                .css('animationName')
                            ;
                            $clone.detach().insertAfter($module);
                            inAnimation = $clone
                                .addClass(className.inward)
                                .css('animationName')
                            ;
                            if (!displayType) {
                                $clone.detach().insertAfter($module);
                                displayType = $clone
                                    .attr('class', elementClass)
                                    .removeAttr('style')
                                    .removeClass(className.hidden)
                                    .removeClass(className.visible)
                                    .show()
                                    .css('display')
                                ;
                                module.verbose('Determining final display state', displayType);
                                module.save.displayType(displayType);
                            }

                            $clone.remove();
                            if (currentAnimation !== inAnimation) {
                                module.debug('Direction exists for animation', animation);
                                directionExists = true;
                            } else if (currentAnimation === 'none' || !currentAnimation) {
                                module.debug('No animation defined in css', animation);

                                return;
                            } else {
                                module.debug('Static animation found', animation, displayType);
                                directionExists = false;
                            }
                            module.save.transitionExists(animation, directionExists);
                        }

                        return transitionExists !== undefined
                            ? transitionExists
                            : directionExists;
                    },
                    animate: function () {
                        // can transition does not return a value if animation does not exist
                        return module.can.transition() !== undefined;
                    },
                },

                is: {
                    animating: function () {
                        return $module.hasClass(className.animating);
                    },
                    inward: function () {
                        return $module.hasClass(className.inward);
                    },
                    outward: function () {
                        return $module.hasClass(className.outward);
                    },
                    looping: function () {
                        return $module.hasClass(className.looping);
                    },
                    occurring: function (animation) {
                        animation = animation || settings.animation;
                        animation = '.' + animation.replace(' ', '.');

                        return $module.filter(animation).length > 0;
                    },
                    visible: function () {
                        return $module.is(':visible');
                    },
                    hidden: function () {
                        return $module.css('visibility') === 'hidden';
                    },
                    supported: function () {
                        // keep method for backward compatibility until 2.10.0
                        return true;
                    },
                },

                hide: function () {
                    if (settings.onHide.call(element) === false) {
                        module.verbose('Hide callback returned false cancelling hide');

                        return false;
                    }
                    module.verbose('Hiding element');
                    if (module.is.animating()) {
                        module.reset();
                    }
                    element.blur(); // IE will trigger focus change if element is not blurred before hiding
                    module.remove.display();
                    module.remove.visible();
                    settings.onBeforeHide.call(element, module.hideNow);
                },

                hideNow: function () {
                    module.set.hidden();
                    module.force.hidden();
                    settings.onHidden.call(element);
                    settings.onComplete.call(element);
                },

                show: function (display) {
                    if (module.force.visible() && settings.onShow.call(element) !== false) {
                        module.verbose('Showing element', display);
                        module.remove.hidden();
                        settings.onBeforeShow.call(element, module.showNow);
                    }
                },

                showNow: function () {
                    module.set.visible();
                    settings.onVisible.call(element);
                    settings.onComplete.call(element);
                },

                toggle: function () {
                    if (module.is.visible()) {
                        module.hide();
                    } else {
                        module.show();
                    }
                },

                stop: function () {
                    module.debug('Stopping current animation');
                    $module.triggerHandler('animationend');
                },

                stopAll: function () {
                    module.debug('Stopping all animation');
                    module.remove.queueCallback();
                    $module.triggerHandler('animationend');
                },

                clear: {
                    queue: function () {
                        module.debug('Clearing animation queue');
                        module.remove.queueCallback();
                    },
                },

                enable: function () {
                    module.verbose('Starting animation');
                    $module.removeClass(className.disabled);
                },

                disable: function () {
                    module.debug('Stopping animation');
                    $module.addClass(className.disabled);
                },

                setting: function (name, value) {
                    module.debug('Changing setting', name, value);
                    if ($.isPlainObject(name)) {
                        $.extend(true, settings, name);
                    } else if (value !== undefined) {
                        if ($.isPlainObject(settings[name])) {
                            $.extend(true, settings[name], value);
                        } else {
                            settings[name] = value;
                        }
                    } else {
                        return settings[name];
                    }
                },
                internal: function (name, value) {
                    if ($.isPlainObject(name)) {
                        $.extend(true, module, name);
                    } else if (value !== undefined) {
                        module[name] = value;
                    } else {
                        return module[name];
                    }
                },
                debug: function () {
                    if (!settings.silent && settings.debug) {
                        if (settings.performance) {
                            module.performance.log(arguments);
                        } else {
                            module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
                            module.debug.apply(console, arguments);
                        }
                    }
                },
                verbose: function () {
                    if (!settings.silent && settings.verbose && settings.debug) {
                        if (settings.performance) {
                            module.performance.log(arguments);
                        } else {
                            module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
                            module.verbose.apply(console, arguments);
                        }
                    }
                },
                error: function () {
                    if (!settings.silent) {
                        module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
                        module.error.apply(console, arguments);
                    }
                },
                performance: {
                    log: function (message) {
                        var
                            currentTime,
                            executionTime,
                            previousTime
                        ;
                        if (settings.performance) {
                            currentTime = Date.now();
                            previousTime = time || currentTime;
                            executionTime = currentTime - previousTime;
                            time = currentTime;
                            performance.push({
                                Name: message[0],
                                Arguments: [].slice.call(message, 1) || '',
                                Element: element,
                                'Execution Time': executionTime,
                            });
                        }
                        clearTimeout(module.performance.timer);
                        module.performance.timer = setTimeout(function () { module.performance.display(); }, 500);
                    },
                    display: function () {
                        var
                            title = settings.name + ':',
                            totalTime = 0
                        ;
                        time = false;
                        clearTimeout(module.performance.timer);
                        $.each(performance, function (index, data) {
                            totalTime += data['Execution Time'];
                        });
                        title += ' ' + totalTime + 'ms';
                        if ($allModules.length > 1) {
                            title += ' (' + $allModules.length + ')';
                        }
                        if (performance.length > 0) {
                            console.groupCollapsed(title);
                            if (console.table) {
                                console.table(performance);
                            } else {
                                $.each(performance, function (index, data) {
                                    console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
                                });
                            }
                            console.groupEnd();
                        }
                        performance = [];
                    },
                },
                // modified for transition to return invoke success
                invoke: function (query, passedArguments, context) {
                    var
                        object = instance,
                        maxDepth,
                        found,
                        response
                    ;
                    passedArguments = passedArguments || queryArguments;
                    context = context || element;
                    if (typeof query === 'string' && object !== undefined) {
                        query = query.split(/[ .]/);
                        maxDepth = query.length - 1;
                        $.each(query, function (depth, value) {
                            var camelCaseValue = depth !== maxDepth
                                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
                                : query;
                            if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
                                object = object[camelCaseValue];
                            } else if (object[camelCaseValue] !== undefined) {
                                found = object[camelCaseValue];

                                return false;
                            } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
                                object = object[value];
                            } else if (object[value] !== undefined) {
                                found = object[value];

                                return false;
                            } else {
                                return false;
                            }
                        });
                    }
                    if (isFunction(found)) {
                        response = found.apply(context, passedArguments);
                    } else if (found !== undefined) {
                        response = found;
                    }

                    if (Array.isArray(returnedValue)) {
                        returnedValue.push(response);
                    } else if (returnedValue !== undefined) {
                        returnedValue = [returnedValue, response];
                    } else if (response !== undefined) {
                        returnedValue = response;
                    }

                    return found !== undefined
                        ? found
                        : false;
                },
            };
            module.initialize();
        });

        return returnedValue !== undefined
            ? returnedValue
            : this;
    };

    // Records if CSS transition is available
    $.fn.transition.exists = {};

    $.fn.transition.settings = {

        // module info
        name: 'Transition',

        // hide all output from this component regardless of other settings
        silent: false,

        // debug content outputted to console
        debug: false,

        // verbose debug output
        verbose: false,

        // performance data output
        performance: true,

        // event namespace
        namespace: 'transition',

        // delay between animations in group
        interval: 0,

        // whether group animations should be reversed
        reverse: 'auto',

        // animation callback event
        onStart: function () {},
        onComplete: function () {},
        onShow: function () {},
        onBeforeShow: function (callback) {
            callback.call(this);
        },
        onVisible: function () {},
        onHide: function () {},
        onHidden: function () {},
        onBeforeHide: function (callback) {
            callback.call(this);
        },

        // whether timeout should be used to ensure callback fires in cases animationend does not
        useFailSafe: true,

        // delay in ms for fail safe
        failSafeDelay: 100,

        // whether EXACT animation can occur twice in a row
        allowRepeats: false,

        // Override final display type on visible
        displayType: false,

        // animation duration
        animation: 'fade',
        duration: false,

        // new animations will occur after previous ones
        queue: true,

        // whether initially inline hidden objects should be skipped for transition
        skipInlineHidden: false,

        metadata: {
            displayType: 'display',
        },

        className: {
            animating: 'animating',
            disabled: 'disabled',
            hidden: 'hidden',
            inward: 'in',
            loading: 'loading',
            looping: 'looping',
            outward: 'out',
            transition: 'transition',
            visible: 'visible',
        },

        // possible errors
        error: {
            noAnimation: 'Element is no longer attached to DOM. Unable to animate.  Use silent setting to suppress this warning in production.',
        },

    };
})(jQuery, window, document);
